<script setup lang="ts">
import { FitAddon } from '@xterm/addon-fit';
import { Terminal } from '@xterm/xterm';
import { onMounted, onUnmounted, ref, type Ref } from 'vue';
import { sendCommand } from '@/api/docker';
import { getMqttClient } from '@/utils/mqtt';
import type { MqttClient } from 'mqtt';
import type { Term } from '@/api/docker/type';

const term = defineModel() as Ref<Term>;

const terminal = ref({} as Terminal);
const terminalContainer = ref<HTMLElement | null>(null);
const fitAddon = ref({} as FitAddon);

const mqttClient = ref({} as MqttClient)

onMounted(() => {
    initClient();
    initTerm();
})


onUnmounted(() => {
    window.removeEventListener('resize', () => {
        fitAddon.value.fit();
    });
})

const send = (command: string) => {
    if (term.value.instanceId != undefined && term.value.executeId != undefined) {
        sendCommand(term.value.instanceId, term.value.executeId, command).then((res) => {})
    }
}

const initClient = () => {
    const client = getMqttClient();
    const topic = "/execute/message/" + term.value.executeId;
    client.subscribe(topic);
    console.log("开始监听：",topic)
    client.on('message', (topic, message) => {
        // console.log('收到消息', topic, message.toLocaleString());
        terminal.value.write(message.toString());
    })
    return client;
}

const initTerm = () => {
    terminal.value = new Terminal()
    fitAddon.value = new FitAddon();
    terminal.value.loadAddon(fitAddon.value);
    send(term.value.input);
    terminal.value.onData((input)=>{
        // 处理特殊按键（如回车键）
        if (input === '\r') { // 回车键
            terminal.value.write('\r'); // 换行并显示新的提示符
            send(term.value.input);
            term.value.input = '';
        } else if (input === '\x7F') { // 退格键
            term.value.input = term.value.input.slice(0,-1);
            terminal.value.write('\b \b'); // 删除一个字符
        } else {
            terminal.value.write(input); // 显示用户输入
            term.value.input = term.value.input + input;
        }
    })
    if (terminalContainer.value) {
        terminal.value.open(terminalContainer.value);
    }
    // 监听窗口大小变化，调整终端大小
    window.addEventListener('resize', () => {
        fitAddon.value.fit();
    });
}
</script>

<template>
    <div ref="terminalContainer" class="terminal-container"></div>
</template>

<style lang="scss" scoped>
.terminal-container {
    display: flex;
    height: 100%;
    width: 100%;
}
</style>